using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Framework.Interop;

namespace Framework
{
	// FIXME: This type should notify the system of changes to the menu
	///<summary>
	///</summary>
	public class ShellMenuItem
	{
		private const int ID_NOT_ASSIGNED = -1;

		///<summary>
		///</summary>
		///<returns></returns>
		public static ShellMenuItem CreateSeparator()
		{
			return new ShellMenuItem(null, false, false, true, null, false, true, null, null);
		}

		///<summary>
		///</summary>
		public ShellMenuItem() : this(null, false, false, true, null, false, false, null, null)
		{
		}

		///<summary>
		///</summary>
		///<param name="text"></param>
		///<param name="verb"></param>
		public ShellMenuItem(string text, string verb) : this(null, false, false, true, null, false, false, text, verb)
		{
		}

		///<summary>
		///</summary>
		///<param name="text"></param>
		///<param name="verb"></param>
		///<param name="onClick"></param>
		public ShellMenuItem(string text, string verb, EventHandler onClick)
			: this(null, false, false, true, null, false, false, text, verb)
		{
			Click += onClick;
		}

		protected ShellMenuItem(Bitmap bitmap, bool @checked, bool @default, bool enabled, string helpText,
								bool radioCheck, bool separator, string text, string verb)
		{
			this.Bitmap = bitmap;
			this.Checked = @checked;
			this.Default = @default;
			this.Enabled = enabled;
			this.HelpText = helpText;
			this.RadioCheck = radioCheck;
			this.Separator = separator;
			this.Text = text;
			this.Verb = verb;
		}

		///<summary>
		///</summary>
		public Bitmap Bitmap { get; set; }

		///<summary>
		///</summary>
		public bool Checked { get; set; }

		///<summary>
		///</summary>
		public event EventHandler Click;

		///<summary>
		///</summary>
		public bool Default { get; set; }

		///<summary>
		///</summary>
		public bool Enabled { get; set; }

		///<summary>
		///</summary>
		public string HelpText { get; set; }

		///<summary>
		///</summary>
		public bool RadioCheck { get; set; }

		///<summary>
		///</summary>
		public bool Separator { get; set; }

		///<summary>
		///</summary>
		public string Text { get; set; }

		///<summary>
		///</summary>
		public string Verb { get; set; }

		internal void CreateMenuItem(IntPtr hMenu, uint index, int id, bool @isDefault)
		{
			// create a MenuItemInfo describing this item

			var mii = new MenuItemInfo
						  {
							  cbSize = checked((uint)Marshal.SizeOf(typeof (MenuItemInfo))),
							  fMask = (this.Bitmap != null ? MenuItemInfoOptions.Bitmap : MenuItemInfoOptions.None) |
									  (this.RadioCheck || this.Separator
										   ? MenuItemInfoOptions.FType
										   : MenuItemInfoOptions.None) |
									  MenuItemInfoOptions.Id |
									  MenuItemInfoOptions.State |
									  MenuItemInfoOptions.String
						  };

			if (this.RadioCheck)
			{
				mii.fType = MenuItemTypes.RadioCheck;
			}
			else if (this.Separator)
			{
				mii.fType = MenuItemTypes.Separator;
			}

			mii.fState =
				(this.Checked ? MenuItemStates.Checked : MenuItemStates.Unchecked) |
				(this.Enabled ? MenuItemStates.Enabled : MenuItemStates.Disabled) |
				(isDefault ? MenuItemStates.Default : MenuItemStates.None);

			mii.wID = checked ((uint)id);

			mii.dwTypeData = this.Text;

			mii.cch = (uint)this.Text.Length;

			mii.hbmpItem = this.Bitmap == null ? IntPtr.Zero : this.Bitmap.GetHbitmap();

			// add the menu item
			User32.InsertMenuItem(hMenu, index, true, ref mii);

			// FIXME: Invoke DrawMenuItem?
		}

		internal void PerformClick(IWin32Window owner, CommandInfo lpici)
		{
			Click(owner, new ContextMenuEventArgs(lpici));
		}
	} ;
}
